# coding: utf-8
from ..op_basic import as_op
import logging
import pandas as pd
import numpy as np

def ts_last_not_zero_index(x):
    '''
    x为ndarray。提取最后一个不为0距离末尾的index。
    '''
    for index, value in enumerate(x):
        if value != 0:
            return len(x) - index
    return -1


def ts_is_increase(x):
    '''
    x为ndarray。是否整体递增（相等也算）
    '''
    previous = None
    for value in x:
        if previous is None:
            previous = value
        else:
            if x < previous:
                return 0
            previous = x
    return 1


def ts_is_decrease(x):
    '''
    x为ndarray。是否整体递减（相等也算）
    '''
    previous = None
    for value in x:
        if previous is None:
            previous = value
        else:
            if x > previous:
                return 0
            previous = x
    return 1

@as_op('ts_window_row_apply')
def ts_window_row_apply(df, func_list, window_list, p_start_time=None, name_list=None, raw=True, prefix=''):
    '''
    df：每一行都是一个时间序列。df.columns为DatetimeIndex。我们要做的就是提取这些时间序列的信息
    func_list：每一个func为ndarray（时间序列）-> 单独特征。也可以是series -> 单独特征。常用的有np.max、np.min、np.sum、np.average等等。
    window_list： 需要计算的窗口的list，如[7, 10, 15]。需要满足window>=1 , window<=len(df.columns)
    p_start_time：预测的时间。我们将会过滤df：df = df[df.columns[df.columns < p_start_time]]。默认预测时间就在这个时间序列之后。
    name_list：对应func_list的名称。默认会直接读取func.__name__
    raw：默认为True，即送给func的是ndarray。会大大加快速度。设置raw=False会送给func Series。
    prefix：提取特征后列名的前缀。
    '''
    logger = logging.getLogger(__name__)
    if p_start_time is not None:
        assert (df.columns.duplicated() == False).all()
        df = df[df.columns[df.columns < p_start_time]]
        logger.warning('use these columns for window cal: %s' % str(df.columns))

    if name_list is None:
        name_list = []
        for func in func_list:
            name_list.append(func.__name__)
    assert len(set(name_list)) == len(name_list)

    for window in window_list:
        assert window >= 1
        assert window <= len(df.columns)
    __raw_columns = []
    for i, func in enumerate(func_list):
        for window in window_list:
            df_ref = df.ix[:, len(df.columns) - window:len(df.columns)]
            temp = df_ref.apply(func, axis=1, raw=raw)
            temp.name = '%s_%s_window%d' % (prefix, name_list[i], window)
            __raw_columns.append(temp)
    return pd.concat(__raw_columns, axis=1)
